<template>
    <div>
        <!-- 面包屑导航区域 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item>集群管理</el-breadcrumb-item>
            <el-breadcrumb-item>集群信息列表</el-breadcrumb-item>
        </el-breadcrumb>

        <!-- 卡片视图区 -->
        <el-card class="box-card">
            <el-row :gutter="20">
                <el-col :span="8">
                    <!-- 搜索与添加区 -->
                    <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getClusterList">
                        <el-button slot="append" icon="el-icon-search" @click="getClusterList"></el-button>
                    </el-input>
                </el-col>
                <el-col :span="2.5">
                    <el-button type="primary" icon="el-icon-circle-plus" @click="showTemplateDialog">添加集群</el-button>
                </el-col>
            </el-row>
        </el-card>

        <!-- 分类列表区 -->
        <tree-table class="treeTable" 
            :data="clusterList" 
            :columns="columns" 
            children-prop="nodes" 
            :selection-type="false" 
            :expand-type="false" 
            show-index 
            index-text="#" 
            border 
            :show-row-hover="false">

            <template slot="row_id" slot-scope="scope">
                <i class="el-icon-more" v-if="!scope.row.cid" style="color: #409EFF"> 集群（ID: <b>{{ scope.row.id }}</b>）</i>
                <i class="el-icon-share" v-else style="color: #67C23A"> 节点（ID: <b>{{ scope.row.id }}）</b></i>
            </template>

            <template slot="ipaddr" slot-scope="scope">
                <div v-if="!scope.row.cid">
                    <el-tag type="info" size="mini" v-if="scope.row.nodes.length <= 0">
                        包含 <b>{{ scope.row.nodes ? scope.row.nodes.length : 0 }}</b> 个节点
                    </el-tag>
                    <el-tag type="primary" size="mini" v-else>
                        包含 <b>{{ scope.row.nodes ? scope.row.nodes.length : 0 }}</b> 个节点
                    </el-tag>
                </div>
                <div v-else>
                    <el-tag type="success" size="mini">
                        {{ scope.row.ipaddr }}
                    </el-tag>
                    <el-tag v-if="scope.row.master" size="mini" effect="dark">主</el-tag>
                </div>
            </template>

            <template slot="db_mode" slot-scope="scope">
                <div v-if="!scope.row.cid">
                    <el-tag size="medium" v-if="scope.row.db_mode == 'oracle'"><i class="el-icon-tickets"></i> ORACLE</el-tag>
                    <el-tag size="medium" v-else-if="scope.row.db_mode == 'pg'" type="success"><i class="el-icon-document-remove"></i> POSTGRES</el-tag>
                    <el-tag size="medium" v-else type="danger"><i class="el-icon-document-delete"></i> UNKNOW</el-tag>
                </div>
            </template>

            <template slot="opt" slot-scope="scope">
                <div v-if="!scope.row.cid">
                    <el-tooltip class="item" effect="dark" content="集群信息" placement="left">
                        <el-button size="mini" icon="el-icon-info" type="success" circle @click="showClusterInfoDialog(scope.row.id)"></el-button>
                    </el-tooltip>
                    <el-tooltip class="item" effect="dark" content="添加节点" placement="top">
                        <el-button size="mini" icon="el-icon-plus" type="primary" circle @click="showNodesDialog(scope.row.id)"></el-button>
                    </el-tooltip>
                    <el-tooltip class="item" effect="dark" content="删除集群" placement="top">
                        <el-button size="mini" icon="el-icon-delete" type="danger" circle @click="removeClusterById(scope.row.id)" :disabled="scope.row.nodes.length > 0"></el-button>
                    </el-tooltip>
                </div>
                <div v-else>
                    <el-tooltip class="item" effect="dark" content="节点信息" placement="left">
                        <el-button size="mini" icon="el-icon-postcard" type="success" circle @click="showNodesDialog(scope.row.cid, scope.row.id)"></el-button>
                    </el-tooltip>
                    <el-tooltip class="item" effect="dark" content="删除节点" placement="right">
                        <el-button size="mini" icon="el-icon-delete" type="danger" circle @click="removeNodeById(scope.row.cid, scope.row.id)"></el-button>
                    </el-tooltip>
                </div>
            </template>
        </tree-table>

        <!-- 分页区域 -->
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum"
            :page-sizes="[1, 2, 5, 10]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
        </el-pagination>


        <!-- 模板选择的对话框 -->
        <el-dialog title="选择集群通用配置模板" :visible.sync="templateDialogVisible" width="60%" @close="templateDialogClosed">
            <el-alert 
                title="提示：选择一个集群通用配置模板，作为后续创建集群的基础配置信息" 
                description="指定的目标模板参数仍可以在后续步骤中根据实际情况进行调整，且不会影响原始模板的信息内容！" 
                type="warning" 
                :closable="false" 
                show-icon 
                center>
            </el-alert>

            <div style="height:400px;">
                <el-scrollbar style="height:100%">
                    <!-- <el-radio v-model="templateModel" :label="0">不使用模板</el-radio> -->
                    <el-table ref="templateTable" :data="templateList" style="width: 100%">
                        <el-table-column type="index" width="50"></el-table-column>
                        <el-table-column label="模板名称" width="180">
                            <template slot-scope="scope">
                                <el-radio v-model="templateModel" :label="scope.row.id">{{ scope.row.name }}</el-radio>
                            </template>
                        </el-table-column>
                        <el-table-column property="db_port" label="端口"></el-table-column>
                        <el-table-column property="db_user" label="常规用户"></el-table-column>
                        <el-table-column property="db_mode" label="兼容模式"></el-table-column>
                        <el-table-column property="replication_mode" label="复制模式"></el-table-column>
                    </el-table>

                </el-scrollbar>
            </div>

            <span slot="footer" class="dialog-footer">
                <el-button @click="templateDialogVisible=false" icon="el-icon-minus">取 消</el-button>
                <el-button type="primary" @click="chooseTemplate(false)" icon="el-icon-data-board">不使用模板</el-button>
                <el-button type="success" @click="chooseTemplate(true)" icon="el-icon-data-line" :disabled="templateModel == 0">使用模板</el-button>
            </span>
        </el-dialog>

        <!-- 集群信息预览对话框 -->
        <el-dialog :title="`集群 ${clusterModel.name} 信息预览`" :visible.sync="clusterInfoDialogVisible" width="60%" @close="clusterInfoDialogClosed">
            <el-form :model="clusterModel" label-width="180px">
                <el-tabs v-model="clusterInfoTabName">

                    <!-- 常规配置预览选项卡 -->
                    <el-tab-pane label="常规配置" name="tab_0">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="集群名称" prop="name">
                                    <el-input v-model="clusterModel.name" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="SSH监听端口" prop="ssh_port">
                                    <el-input-number v-model="clusterModel.ssh_port" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="系统普通用户名" prop="user_normal">
                                    <el-input v-model="clusterModel.user_normal" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="系统管理员密码" prop="root_password">
                                    <el-input v-model="clusterModel.root_password" type="password" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="数据库安装路径" prop="installation_path">
                                    <el-input :value="clusterModel.installation_path" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="归档文件目录" prop="archive_path">
                                    <el-input :value="clusterModel.archive_path" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-form-item label="信任网关" prop="trust_servers">
                            <el-tag 
                                :key="tag" 
                                v-for="tag in clusterModel.trust_servers">
                                {{tag}}
                            </el-tag>
                        </el-form-item>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="HA日志文件" prop="log_file">
                                    <el-input :value="clusterModel.log_file" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="数据库data目录" prop="data_directory">
                                    <el-input :value="clusterModel.data_directory" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="数据库bin目录" prop="pg_bin_dir">
                                    <el-input :value="clusterModel.pg_bin_dir" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="HA PID文件" prop="hamgr_pid_file">
                                    <el-input :value="clusterModel.hamgr_pid_file" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-tab-pane>

                    <!-- 基本配置预览选项卡 -->
                    <el-tab-pane label="基本配置" name="tab_1">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="最大连接数" prop="max_connections">
                                    <el-input-number v-model="clusterModel.max_connections" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="数据库监听端口" prop="db_port">
                                    <el-input-number v-model="clusterModel.db_port" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="数据库管理员用户" prop="db_user">
                                    <el-input v-model="clusterModel.db_user" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="数据库用户密码" prop="db_password">
                                    <el-input v-model="clusterModel.db_password" type="password" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="复制模式" prop="replication_mode">
                                    <el-select v-model="clusterModel.replication_mode" disabled>
                                        <el-option label="sync" value="sync"></el-option>
                                        <el-option label="async" value="async"></el-option>
                                        <el-option label="quorum" value="quorum"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="兼容模式" prop="db_mode">
                                    <el-select v-model="clusterModel.db_mode" disabled>
                                        <el-option label="oracle" value="oracle"></el-option>
                                        <el-option label="pg" value="pg"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="加密方式" prop="encryption">
                                    <el-select v-model="clusterModel.encryption" disabled>
                                        <el-option label="md5" value="md5"></el-option>
                                        <el-option label="trust" value="trust"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="HA库名" prop="hamgr_dbname">
                                    <el-input v-model="clusterModel.hamgr_dbname" disabled></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="HA库用户" prop="hamgr_dbuser">
                                    <el-input v-model="clusterModel.hamgr_dbuser" disabled></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-form-item label="ping命令路径" prop="ping_path">
                            <el-input v-model="clusterModel.ping_path" readonly></el-input>
                        </el-form-item>
                    </el-tab-pane>

                    <!-- 高级配置预览选项卡 -->
                    <el-tab-pane label="高级配置" name="tab_2">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="备服务器WAL文件数" prop="wal_keep_segments">
                                    <el-input-number v-model="clusterModel.wal_keep_segments" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="进程最大数" prop="max_wal_senders">
                                    <el-input-number v-model="clusterModel.max_wal_senders" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="热备反馈" prop="hot_standby_feedback">
                                    <el-select v-model="clusterModel.hot_standby_feedback" disabled>
                                        <el-option label="on" value="on"></el-option>
                                        <el-option label="off" value="off"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="编码格式" prop="server_encoding">
                                    <el-select v-model="clusterModel.server_encoding" disabled>
                                        <el-option label="default" value="default"></el-option>
                                        <el-option label="utf8" value="utf8"></el-option>
                                        <el-option label="gbk" value="gbk"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="虚拟IP地址" prop="virtual_ip">
                                    <el-input v-model="clusterModel.virtual_ip" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="虚拟子网掩码" prop="virtual_ip_mask">
                                    <el-input v-model="clusterModel.virtual_ip_mask" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="arping命令路径" prop="arping_path">
                                    <el-input v-model="clusterModel.arping_path" readonly></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="ip命令路径" prop="ip_path">
                                    <el-input v-model="clusterModel.ip_path" readonly></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-form-item label="SSH 参数" prop="ssh_options">
                            <el-input v-model="clusterModel.ssh_options" readonly></el-input>
                        </el-form-item>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="重连尝试次数" prop="reconnect_attempts">
                                    <el-input-number v-model="clusterModel.reconnect_attempts" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="重连次数间隔" prop="reconnect_interval">
                                    <el-input-number v-model="clusterModel.reconnect_interval" disabled></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="故障转移方式" prop="failover">
                                    <el-select v-model="clusterModel.failover" disabled>
                                        <el-option label="manual" value="manual"></el-option>
                                        <el-option label="automatic" value="automatic"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="恢复方式" prop="recovery">
                                    <el-select v-model="clusterModel.recovery" disabled>
                                        <el-option label="manual" value="manual"></el-option>
                                        <el-option label="automatic" value="automatic"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-tab-pane>

                </el-tabs>
            </el-form>

            <span slot="footer" class="dialog-footer">
                <el-button type="danger" @click="clusterInfoDialogVisible=false">关闭</el-button>
            </span>
        </el-dialog>

        <!-- 预览节点信息对话框 -->
        <el-dialog :title="`集群 ${this.clusterModel.name} 节点信息`" :visible.sync="nodesDialogVisible" width="800px">

            <el-collapse v-model="collapseActiveName" accordion>
                <el-collapse-item v-for="(item) in clusterModel.nodes" :key="item.id" :name="item.name">
                    <template slot="title">
                        <i class="el-icon-share" style="color: #67C23A">
                             - <b>{{ item.name }}</b>
                             - 
                            <el-tag v-if="item.master" effect="dark" size="mini">主</el-tag>
                            <el-tag v-else effect="plain" size="mini">备</el-tag>
                        </i>
                    </template>
                    <el-tag type="info">节点 ID：<b>{{ item.id }}</b></el-tag>
                    <el-tag type="info">集群 ID：<b>{{ item.cid }}</b></el-tag>
                    <el-tag type="info">节点名称：<b>{{ item.name }}</b></el-tag>
                    <el-tag type="info">节点 IP 地址：<b>{{ item.ipaddr }}</b></el-tag>
                </el-collapse-item>
            </el-collapse>

            <span slot="footer" class="dialog-footer">
                <el-button type="danger" @click="nodesDialogVisible=false">关闭</el-button>
            </span>
        </el-dialog>

    </div>
</template>

<script>
export default {
    data: function () {
        return {
            queryInfo: {
                query: '',
                pagenum: 1,
                pagesize: 5
            },
            clusterList: [],
            total: 0,
            columns: [
                {
                    label: '集群 / 节点名称',
                    prop: 'name'
                },
                {
                    label: '集群 / 节点ID',
                    type: 'template',
                    template: 'row_id',
                },
                {
                    label: '节点数 / IP 地址',
                    type: 'template',
                    template: 'ipaddr'
                },
                {
                    label: '兼容模式',
                    type: 'template',
                    template: 'db_mode',
                },
                {
                    label: '操作',
                    type: 'template',
                    template: 'opt',
                    width: '150px'
                }
            ],
            templateList: [],
            templateDialogVisible: false,
            templateModel: 0,
            clusterInfoDialogVisible: false,
            clusterInfoTabName: 'tab_0',
            clusterModel: {},
            nodesDialogVisible: false,
            collapseActiveName: 'node01'
        }
    },
    created: function () {
        this.getClusterList();
    },
    methods: {
        getClusterList: async function () {
            const result = await this.$http.get('clusters', {
                params: this.queryInfo
            });
            const res = result.data;
            if (res.meta.status !== 200) return this.$message.error(`获取集群列表失败：${res.meta.msg}`);

            this.clusterList = res.data.clusters;
            this.total = res.data.totalpage;
            // console.log(this.clusterList);
        },
        getTemplateList: async function () {
            const result = await this.$http.get('templates', {
                params: {
                    query: '',
                    pagenum: 1,
                    pagesize: 9999
                }
            });
            const res = result.data;
            if (res.meta.status !== 200) return this.$message.error(`获取通用配置模板列表失败：${res.meta.msg}`);
            this.templateList = res.data.templates;
            // this.templatesTotal = res.data.totalpage;
        },
        getClusterInfoById: async function (cid) {
            const result = await this.$http.get(`clusters/${cid}`);
            const res = result.data;
            if (res.meta.status !== 201) return this.$message.error(`获取集群信息失败：${res.meta.msg}`);
            return res.data;
        },
        handleSizeChange: function (newPageSize) {
            // 前往页数改变时触发
            this.queryInfo.pagesize = newPageSize;
            this.getClusterList();
        },
        handleCurrentChange: function (newPage) {
            // 点击页码时触发
            this.queryInfo.pagenum = newPage;
            this.getClusterList();
        },
        showTemplateDialog: async function () {
            await this.getTemplateList();
            if (!this.templateList) return;
            this.templateDialogVisible = true;
        },
        templateDialogClosed: function () {
            this.templateModel = 0;
        },
        chooseTemplate: function (useTemplate) {
            this.$router.push({
                path: '/cluster/add',
                query: { 
                    tid: useTemplate ? this.templateModel : 0,
                }
            });
        },
        showClusterInfoDialog: async function (cid) {
            const data = await this.getClusterInfoById(cid);
            if (!data) return;
            this.clusterModel = data;
            this.clusterInfoDialogVisible = true;
        },
        clusterInfoDialogClosed: function () {
            this.clusterModel = {};
            this.clusterInfoTabName = 'tab_0';
        },
        removeClusterById: async function (id) {
            // 查询子节点是否为空
            const queryResult = await this.$http.get(`clusters/${id}`);
            const queryRes = queryResult.data;
            if (queryRes.meta.status !== 201) return this.$message.error(`获取集群 (${queryRes.data.name}) 最新信息失败: ${queryRes.meta.msg}`);
            const nodeCount= queryRes.data.nodes.length;
            if (nodeCount > 0) return this.$message.warning(`集群 (${queryRes.data.name}) 下存在 ${nodeCount} 个节点，不允许直接删除！`);

            // 开始删除集群
            const rm = await this.$confirm('此操作将永久删除该集群, 是否继续?', '确认', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).catch(err => err);
            if (rm !== 'confirm') return this.$message.info('已取消删除');

            const result = await this.$http.delete(`clusters/${id}`);
            const res = result.data;

            if (res.meta.status !== 200) return this.$message.error(`删除集群失败: ${res.meta.msg}`);
            this.$message.success('删除集群成功');

            // 刷新集群列表
            this.getClusterList();
        },
        showNodesDialog: async function (cid, id) {
            const data = await this.getClusterInfoById(cid);
            if (!data) return;
            this.clusterModel = data;
            if (id) {
                this.collapseActiveName = data.nodes.find(item => item.id === id).name;
                this.nodesDialogVisible = true;
            } else {
                this.$router.push({
                    path: '/node/add',
                    query: {
                        clusterModel: this.clusterModel
                    }
                });
            }
        },
        removeNodeById: async function (cid, id) {
            // 开始删除集群
            const rm = await this.$confirm('此操作将永久删除该节点, 是否继续?', '确认', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).catch(err => err);
            if (rm !== 'confirm') return this.$message.info('已取消删除');

            const result = await this.$http.delete(`nodes/${cid}/${id}`);
            const res = result.data;

            if (res.meta.status !== 200) return this.$message.error(`删除节点失败: ${res.meta.msg}`);
            this.$message.success('删除节点成功');

            // 刷新集群列表
            this.getClusterList();
        }
    }
}
</script>

<style lang="less" scoped>
    .treeTable {
        margin-top: 15px;
    }
    .radioItem {
        margin-bottom: 10px;
    }
    .el-alert {
        margin-bottom: 15px;
    }
    .el-tag {
        margin-right: 10px;
    }

    .el-select, .el-input-number {
        width: 100%;
    }
</style>